<template>
  <!--#region 字段管理弹出层-->
  <el-popover
    ref="fieldPopoverRef"
    :virtual-ref="virtualRef"
    :visible="fieldManagementVisible"
    :show-arrow="false"
    transition="el-zoom-in-top"
    placement="bottom-start"
    :offset="0"
    width="320px"
    @hide="renameColumn = ''"
  >
    <div v-click-popover-outside="() => toggleFieldManagementVisible(false)">
      <h1 class="font-semibold text-xl text-gray-800 mb-4">字段管理</h1>
      <el-scrollbar :max-height="480" view-class="pr-4">
        <draggable
          v-model="tabulatorColumns"
          item-key="field"
          handle=".i-lucide-grip-vertical"
          @change="onDragSorting"
        >
          <template #item="{ element: col }">
            <div
              class="flex items-center gap-x-2 py-2 px-4 rounded-md hover:bg-gray-200 text-lg"
            >
              <div class="shrink-0">
                <i class="i-lucide-grip-vertical cursor-move text-[18px]" />
              </div>
              <span
                v-if="renameColumn !== col.field"
                class="inline-block grow truncate leading-none"
              >
								{{ col.title }}
							</span>
              <el-input
                v-else
                ref="renameInputRef"
                v-model="col.title"
                class="w-full"
                auto-focus
                @keyup.enter="onRenameColumn(col)"
              />
              <div class="flex gap-x-2 shrink-0">
                <div
                  class="flex items-center hover:bg-gray-300 hover:text-gray-800 rounded-md p-1"
                  @click="onToggleColumnVisible(col as ColumnDefinition)"
                >
                  <i
                    :class="[
											col.visible ? 'i-lucide-eye' : 'i-lucide-eye-closed',
											'text-[18px]'
										]"
                  />
                </div>
                <div
                  class="flex items-center hover:bg-gray-300 hover:text-gray-800 rounded-md p-1"
                  @click="onToggleRenameColumn(col)"
                >
                  <i class="i-lucide-square-pen text-[18px]" />
                </div>
              </div>
            </div>
          </template>
        </draggable>
      </el-scrollbar>
    </div>
  </el-popover>
  <!--#endregion-->
</template>
<script setup lang="ts">
import type { ColumnDefinition, Tabulator } from 'tabulator-tables'
import { ElInput } from 'element-plus'
import draggable from 'vuedraggable'
import { clickPopoverOutside as vClickPopoverOutside } from '../directives'
import type { DragSortingEvent } from '../types'
import { useToggle } from '@vueuse/core'
import { ref, nextTick } from 'vue'

const props = defineProps<{
  viewId: string
  virtualRef: any
  tabulator: Tabulator | null
}>()
const emit = defineEmits<{
  'update:definition': []
}>()

const tabulatorColumns = defineModel<ColumnDefinition[]>({ required: true })

// 字段管理面板
const fieldPopoverRef = ref()
// 字段管理面板可见状态
const [ fieldManagementVisible, toggleFieldManagementVisible ] = useToggle(false)

// 字段拖拽排序
const onDragSorting = ({ moved }: DragSortingEvent<ColumnDefinition>) => {
  const { newIndex, oldIndex, element } = moved
  const rel = newIndex > oldIndex ? -1 : 1
  props.tabulator?.moveColumn(
    element.field!,
    tabulatorColumns.value.at(newIndex + rel)?.field!,
    newIndex > oldIndex
  )
  emit('update:definition')
}

// 字段重命名
const renameColumn = ref('')
const renameInputRef = ref()
const onRenameColumn = async (col: ColumnDefinition) => {
  await props.tabulator?.updateColumnDefinition(col.field!, col)
  renameColumn.value = ''
  emit('update:definition')
}

// 切换重命名输入框绑定的字段
const onToggleRenameColumn = (col: ColumnDefinition) => {
  renameColumn.value = col.field as string
  nextTick(() => {
    renameInputRef.value.focus()
  })
}

// 切换列是否可见
const onToggleColumnVisible = (col: ColumnDefinition) => {
  if (col.visible) {
    props.tabulator?.hideColumn(col.field)
  } else {
    props.tabulator?.showColumn(col.field)
  }
  col.visible = !col.visible
  emit('update:definition')
}

defineExpose({
  toggleVisible: toggleFieldManagementVisible
})
</script>
